<?php
/**
 * Celebrio Core
 * 
 * @copyright  Copyright (c) 2011 Celebrio Software
 * @package    Celebrio
 * @subpackage Core
 */
namespace Celebrio\Core;

use Nette\Object;

use Celebrio\Core\Manifest;
use Celebrio\Core\ServiceProvider;

/**
 * Handles the module installation (the activation in the system) which
 * always includes creating config file, sometimes also database records,
 * initial file/folder creating or configuring and so on.
 *
 * @author pavel
 */
class ModuleInstaller extends Object {
    
    public function install(Manifest $manifest, $configuration = array()) {
        
        $this->checkDependencies($manifest);
        
        if ($manifest->isAbstract()) {
            throw new \Exception("Trying to install abstract module directly");
        }
        
        // register globaly accessible service
        ServiceProvider::registerService($manifest);
        
        // initialize via module init class
        $this->initClassInstall($manifest, $configuration);
        // set abstract installed in installed.ini
        if ($manifest->isImpl()) {
            $manifestLoader = new ManifestLoader();
            $abstract = $manifestLoader->getAbstract($manifest);
            Config::current()->install($abstract->getFullNameDots());
        }
        
        // set implementation/service/app installed in installed.ini
        Config::current()->install($manifest->getFullNameDots());
    }

    public function uninstall(Manifest $manifest, $abstract = false) {

        // TODO: check dependencies

        if ($manifest->isAbstract() && !$abstract) {
            throw new \Exception("Trying to uninstall abstract module directly.");
        }
        $initClass = $manifest->getInit();
        if ($initClass !== null) {
            $initClass->uninstall();
        } else {
            throw new \Exception("Null init class when trying to uninstall module.");
        }
        Config::current()->uninstall($manifest->getFullNameDots());

        // TODO: check whether only abstract module was left behind
    }
    
    private function initClassInstall(Manifest $manifest, $configuration) {
        $initClass = $manifest->getInit();
        if ($initClass !== null) {
            $newConfig = $initClass->changeConfig($configuration);
            $initClass->install($newConfig);
            Config::current()->saveConfigArray($newConfig, $manifest->getFullNameDots());
        }
    }
    
    private function findAbstract(Manifest $manifest) {
        
    }
    
    private function checkDependencies(Manifest $manifest) {
        //\Nette\Debug::dump("Dependencies are OK for now (testing version).");
    }

}

